摘要:
11 旋转数组的最小数字
12 矩阵的路径
13 机器人的运动范围
面试题11 旋转数组的最小数字
题目:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
解法:
思路一:
遍历数组查询到反转点,时间复杂度未O(n),空间复杂度O(1);
1 | class Solution { |
1 | class Solution: |
思路二:
使用二分法查找数组元素,时间复杂度降低至对数级别:
1 | class Solution { |
1 | class Solution: |
面试题12 矩阵的路径
题目:
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[[“a”,”b”,”c”,”e”],
[“s”,”f”,”c”,”s”],
[“a”,”d”,”e”,”e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
解法:
深度优先搜索(DFS)+ 剪枝
- 递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k 。
- 终止条件:
1.返回 falsefalse : ① 行或列索引越界 或 ② 当前矩阵元素与目标字符不同 或 ③ 当前矩阵元素已访问过 。
2.返回 truetrue : 字符串 word 已全部匹配,即 k = len(word) - 1 。
- 递推工作:
1.标记当前矩阵元素: 将 board[i][j] 值暂存于变量 tmp ,并修改为字符 ‘/‘ ,代表此元素已访问过,防止之后搜索时重复访问。
2.搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需一条可行路径) ,并记录结果至 res 。
3.还原当前矩阵元素: 将 tmp 暂存值还原至 board[i][j] 元素。
- 回溯返回值: 返回 res ,代表是否搜索到目标字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Solution {
public boolean exist(char[][] board, String word) {
char[] words=word.toCharArray();
for(int i=0;i<board.length;i++){
for(int j=0;j<board[0].length;j++){
if(dfs(board,words,i,j,0)) return true;
}
}
return false;
}
public boolean dfs(char[][] board,char[] words,int i,int j,int k){
if(i<0||i>board.length-1||j<0||j>board[0].length-1||words[k]!=board[i][j]) return false;
if(k==words.length-1) return true;
boolean res;
char tmp=board[i][j];
board[i][j]='/';
res=dfs(board,words,i+1,j,k+1)||dfs(board,words,i-1,j,k+1)|dfs(board,words,i,j+1,k+1)||dfs(board,words,i,j-1,k+1);
board[i][j]=tmp;
return res;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
def dfs(i, j, k):
if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: return False
if k == len(word) - 1: return True
tmp, board[i][j] = board[i][j], '/'
res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
board[i][j] = tmp
return res
for i in range(len(board)):
for j in range(len(board[0])):
if dfs(i, j, 0): return True
return False面试题13 机器人的运动范围
题目:
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
解法一:深度优先遍历
1 | class Solution { |
1 | class Solution: |
解法二:广度优先遍历
1 | // 广度优先遍历 |
1 | # 广度优先遍历 |